package com.lzy.securityResources.config;

import cn.hutool.core.util.StrUtil;
import com.lzy.system.organization.entity.SysRes;
import com.lzy.system.organization.service.ISysResRoleService;
import com.lzy.utils.PublicVar;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Component
public class RolePermissionMetadataSource implements FilterInvocationSecurityMetadataSource {

    private ISysResRoleService iSysResRoleService;

    AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Autowired
    public RolePermissionMetadataSource(ISysResRoleService iSysResRoleService) {
        this.iSysResRoleService = iSysResRoleService;
    }

    @Override
    public Collection<ConfigAttribute> getAttributes(Object object)
            throws IllegalArgumentException {
        FilterInvocation invocation = (FilterInvocation) object;
        String url = invocation.getRequestUrl();
        List<String> query_url = new ArrayList<>();
        String[] url_split = url.split("/");
        for (String s : url_split) {
            if(StrUtil.isBlank(s)){
                continue;
            }
            if (query_url.size()>=2) {
                break;
            }
            query_url.add(s);
        }

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        for (String s : PublicVar.AUTH_WHITELIST) {
            if (antPathMatcher.match(s, url)) {
                return null;
            }
        }

        //通过用户查找角色所有的权限
        if (!(authentication instanceof AnonymousAuthenticationToken)) {
            String currentUserName = authentication.getName();
            //判断添加角色
            List<SysRes> sysRes = iSysResRoleService.queryByUidAndUrl(currentUserName,"/"+String.join("/",query_url));
            for (SysRes sysRe : sysRes) {
                if (antPathMatcher.match(sysRe.getLink(), url)) {
                    return null;
                }
            }
        }

        // 没有匹配上的资源，禁止访问，设置不存在的访问权限
        // 通过之前的分析知道，如果这里返回空，将会直接放行，运行登录用户访问，这是有风险的
        return SecurityConfig.createList("ROLE_REFUSE");
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return FilterInvocation.class.isAssignableFrom(clazz);
    }
}
